library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

use work.wr_pkg.all;

entity xwr_udp_rx_tb is

end entity;

architecture rtl of xwr_udp_rx_tb is

  component xwr_udp_rx is
  port (
      --// clk, reset
      rst_n_i       : in std_logic;
      --clk_ref_i     : in std_logic;
      clk_sys_i     : in std_logic;

      raw_snk_i     : in  t_wrf_sink_in;
      raw_snk_o     : out t_wrf_sink_out;

      fifo_wrdata_o   : out std_logic_vector(15 downto 0);  -- fifo dout
      fifo_wrclk_o    : out std_logic;
      fifo_wren_o     : out std_logic;
      fifo_full_i     : in  std_logic;
      fifo_prog_full_i: in  std_logic
  );
  end component;

signal fifo_wrdata    : std_logic_vector(15 downto 0);
signal fifo_wrclk     : std_logic;
signal fifo_wren      : std_logic;
signal fifo_full      : std_logic;
signal fifo_prog_full : std_logic;

signal raw_snk_i     : t_wrf_sink_in;
signal raw_snk_o     : t_wrf_sink_out;
signal snk_cnt:integer;
signal snk_wait:std_logic_vector(1 downto 0);
constant data_len: integer:=51;
type data_array is array (natural range <>) of std_logic_vector(15 downto 0);
signal raw_data:data_array(data_len-1 downto 0);

signal clk_sys:std_logic;
signal rst_n:std_logic;

constant clk_period:time:= 16 ns;
constant rst_time: time:= 20 ns;

begin

clk_sys_gen : process  -- 62.5MHz
begin
  clk_sys <= '0';
  wait for clk_period;
  clk_sys <= '1';
  wait for clk_period;
end process;


rst_gen: process
begin
  rst_n <= '0';
  wait for rst_time;
  rst_n <= '1';
  wait for 1 ms;
end process;

inst:xwr_udp_rx
port map(
    rst_n_i       => rst_n,
    clk_sys_i     => clk_sys,

    raw_snk_i     => raw_snk_i,
    raw_snk_o     => raw_snk_o,

    fifo_wrdata_o    => fifo_wrdata,
    fifo_wrclk_o     => fifo_wrclk,
    fifo_wren_o      => fifo_wren,
    fifo_full_i      => fifo_full,
    fifo_prog_full_i => fifo_prog_full
);

fifo_prog_full<='0';
fifo_full <= '0';

raw_snk_o.stall<='0';
raw_snk_o.err<='0';
raw_snk_o.rty<='0';

p_snk_i_data : process(clk_sys,rst_n)
begin
    if rising_edge(clk_sys) then
        if rst_n='0' then
            raw_snk_i.adr<="00";
            raw_snk_i.dat<=(others=>'0');
            raw_snk_i.cyc<='0';
            raw_snk_i.stb<='0';
            raw_snk_i.we <='1';
            raw_snk_i.sel <="11";
            snk_wait <="00";
        else
            if snk_wait="00" then
              raw_snk_i.cyc<='1';
              raw_snk_i.stb<='1';
              raw_snk_i.dat<= raw_data(snk_cnt);
              if snk_cnt=0 then
                snk_wait <="01";  
              end if ;
            elsif snk_wait ="01" then
                snk_wait <= "00";
                raw_snk_i.cyc<='0';
                raw_snk_i.stb<='0';
                raw_snk_i.dat<= (others=>'0');
            end if ;
        end if ;
    end if ;
end process ; -- p_data

p_snk_count:process(clk_sys,rst_n)
begin
    if rising_edge(clk_sys) then
        if rst_n='0' then
            snk_cnt<=data_len-1;
        else
            if snk_cnt > 0 then
                snk_cnt <= snk_cnt-1;
            else
                snk_cnt<=data_len;  
            end if ;
        end if ;
    end if ;
end process ; -- p_data

raw_data <= (
x"2233",
x"076C",
x"B3B5",  --  dst mac addr
x"8CAE",
x"4B00",
x"2F40",  -- my mac addr
x"0800",  -- ethernet type 0x0800, 0x0806, 0x0835
x"4500",  -- ip version (4) + head length (5) + Differentiated Services(00)  -- ip start
x"0058",  -- total length
x"8D20", -- Identification
x"4000",  --  Don't Fragment(4) + Fragment offset (000)
x"4011",  -- time to live (40) + protocol (udp:0x11, tcp/icmp:0x06)
x"2BFF", -- header checksum
x"C0A8", 
x"0001",  -- dst ip
x"C0A8",
x"0024",  -- my ip                                                                                                    -- ip end
x"ABCD", -- src port
x"ABCD", -- dst port
x"0044",   -- length
x"FE7E",  -- udp checksum
x"0001",  -- 02
x"0203",  -- 04
x"0405",  -- 06
x"0607",  -- 08
x"0809",  -- 0a
x"0a0b",  -- 0c
x"0c0d",  -- 0e
x"0e0f",  -- 10
x"1011",  -- 12
x"1213",  -- 14
x"1415",  -- 16
x"1617",  -- 18
x"1819",  -- 1a
x"1a1b",  -- 1c
x"1c1d",  -- 1e
x"1e1f",  -- 20
x"2021",  -- 22
x"2223",  -- 24
x"2425",  -- 26
x"2627",  -- 28
x"2829",  -- 2a
x"2a2b",  -- 2c
x"2c2d",  -- 2e
x"2e2f",  -- 30
x"3031",  -- 32
x"3233",  -- 34
x"3435",  -- 36
x"3637",  -- 38
x"3839",  -- 3a
x"3a3b"  -- 3c
);

--raw_data <= (
--x"2233",
--x"076C",
--x"B3B5",  --  dst mac addr
--x"8CAE",
--x"4B00",
--x"2F40",  -- my mac addr
--x"0800",  -- ethernet type 0x0800, 0x0806, 0x0835
--x"4500",  -- ip version (4) + head length (5) + Differentiated Services(00)  -- ip start
--x"0058",  -- total length
--x"8D20", -- Identification
--x"4000",  --  Don't Fragment(4) + Fragment offset (000)
--x"4011",  -- time to live (40) + protocol (udp:0x11, tcp/icmp:0x06)
--x"2BFF", -- header checksum
--x"C0A8", 
--x"0001",  -- dst ip
--x"C0A8",
--x"0024",  -- my ip                                                                                                    -- ip end
--x"ABCD", -- src port
--x"ABCD", -- dst port
--x"0044",   -- length
--x"FE7E",  -- udp checksum
--x"4865",  -- 02
--x"6C6C",  -- 04
--x"6F2C",  -- 06
--x"2057",  -- 08
--x"6F72",  -- 0a
--x"6C64",  -- 0c
--x"2143",  -- 0e
--x"6F6D",  -- 10
--x"6520",  -- 12
--x"6F6E",  -- 14
--x"2062",  -- 16
--x"6162",  -- 18
--x"7921",  -- 1a
--x"476F",  -- 1c
--x"2047",  -- 1e
--x"6F20",  -- 20
--x"476F",  -- 22
--x"214D",  -- 24
--x"6179",  -- 26
--x"2062",  -- 28
--x"6520",  -- 2a
--x"666F",  -- 2c
--x"7263",  -- 2e
--x"6520",  -- 30
--x"6265",  -- 32
--x"2077",  -- 34
--x"6974",  -- 36
--x"6820",  -- 38
--x"796F",  -- 3a
--x"7521"  -- 3c
--);

end architecture ; -- rtl
